# -*- coding: utf-8 -*-#

#-------------------------------------------------------------------------------
# Name:         pandas_dataframe_oprations
# Description:  pandas的各种操作范例
# Author:       ylf
# Date:         8/13/21
#-------------------------------------------------------------------------------

import pandas as pd


# ----------------------------------------查询---------------------------------
data1={"bookname":['python入门', 'python精通', 'python放弃'],
      "author":['james', 'jack', 'deltaf'],
      "price":['38.9','35.3','36.6'],
       "date":['20200-01-02', '2021-07-08', '2021-09-01']
      }
df1 = pd.DataFrame(data1)
print(df1)


# ----------------------------------------查询---------------------------------
# loc( )	通过标签或布尔数字查询数据集 （推荐使用的查询方法）


# 1.1.1  查行
print(df1.loc[1])
# bookname      python精通
# author            jack
# price             35.3
# date        2021-07-08
# Name: 1, dtype: object


# 1.1.2  查第二行（也就是列索引为1）,列名为author 的数据
print(df1.loc[1, "author"])
# jack


# 1.1.3  查询多行多列的数据
print(df1.loc[[0, 2], ['bookname', 'author', 'price']])

print('---------------------------1 -------------------------')

# 1.1.4  查询单列
print(df1['bookname'])

# 1.1.5  查询多列
print(df1[['bookname', 'author']])

#    bookname  author
# 0  python入门   james
# 1  python精通    jack
# 2  python放弃  deltaf


#  1.1.6  根据区间来进行查询
print(df1.loc[0:2, ['bookname','author', 'date']])

print('-----------------------------------------loc和iloc-----------------------------------')


# iloc( ）	通过索引位来查询数据集
# loc 和 iloc 的区别
# loc是根据index来的，iloc是根据行号来的，如果index没有指定，那loc和iloc是可以通用的，如果index是乱的
# 比如index=[0 1 3 5 6]这种，那loc和iloc取出来的值就不同了
data2={"bookname":['python入门', 'python精通', 'python放弃'],
      "author":['james', 'jack', 'deltaf'],
      "price":['38.9','35.3','36.6'],
       "date":['20200-01-02', '2021-07-08', '2021-09-01']
      }
df2=pd.DataFrame(data2)
df2.index=[0, 2, 4]
# 索引不同以后，使用loc 和 iloc 就有区别了
print(df2.loc[2])   # 查询到的是索引为2的那一行，也就是第二行
print('------------')
print(df2.iloc[2])  # 查询到的是行号为2的那一行，也就是第三行



# query( )	通过布尔表达式查询数据列

# 1.1.7 根据条件来进行查询,查询价格大于36的书籍

print(df2.loc[df2['price']>str(36)])
print(df2.loc[(df2['price']>str(36)) & (df2['author']=='james')])
print(df2['price']>str(36))
# 注意观察条件式中的返回结果，是布尔值
# 0     True
# 2    False
# 4     True


# 1.1.8 根据函数进行查询[这个感觉比较好用，到时候可以用]

print(df2.loc[df2['author'].isin(['james'])])






# ----------------------------------------新增---------------------------------
print('----------------------------------------新增---------------------------------')

data3={
    "name":['jack','tom','jerry'],
    "age":[13,15,17],
    "teacher":['MrLi','MissZhang','MrJ'],
    "score":[100,90,56]
}

df3 = pd.DataFrame(data3)
print(df3)





# 2.1  新增列数据

# 2.1.1 直接新增列数据
df3['wife']=['lili', 'lucy', 'Kim']
print(df3)

# 2.1.2 通过insert方法进行添加
df3.insert(5, "father", ['jacks', 'tomas', 'jerrys'],allow_duplicates=False)
print(df3)

# 2.2  新增行数据

# 2.2.1 通过loc方法进行新增
df3.loc[3] = ['chees', 45, "MrT", "55", "jim", "old chees"]
print(df3)

# 2.2.2 通过append方法进行新增
df3.append(['tiger', 34, "MrH", 66, "femaleTiger", "new Tiger"])
print(df3)




# ----------------------------------------删除---------------------------------
# drop (labels=None, axis=0, index=None, columns=None, level=None, inplace=False, errors=‘raise’)
# labels	标签（行标签或者列标签）
# axis	表示删除行（axis=0 默认）或者删除列（axis=1）
# index	删除的行索引名
# columns	删除的列索引名
# inplace	指定删除是否要在原数据上进行操作，默认是 False


df4 = df3.copy(deep=True)
print(df4)

# 3.1.1  删除指定的行或者列

df5 = df4.drop(labels=[0, 1]) # 删除第0行和第一行
# print(df5)
# print(df4)   # 默认df4没有被修改，# 如果要删除df4的内容的话
# df4.drop(labels=[0, 1], inplace=True)
# print(df4)

# 如果不是特别的需要，建议不要指定该参数为 True，不然会改变原有数据对其他的分析产生一定的影响。

# 3.1.2 删除指定的列
df6 = df3.drop(labels=['teacher', 'wife'], axis=1)
print(df6)



# 3.2  删除指定条件的行或者列

# 3.2.1 同时删除行和列
df7 = df3.drop(index=3, columns='wife')
print(df7)

# 3.2.1 根据条件删除指定的行或者列，也就是筛选
# 筛选年龄大于16岁的数据

df8 = df3[(df3['age']>16)]
print(df8)



# ----------------------------------------修改---------------------------------
# rename (self, mapper=None, index=None, columns=None, axis=None, copy=True, inplace=False, level=None, errors=‘ignore’)
# mapper	这里是要传入的映射关系，可以是个字典或者函数
# index	指定行索引
# columns	指定列索引
# axis	表示修改行索引（axis=0 默认）还是列索引（axis=1）
# inplace	是否在原数据基础上修改，默认 inplace=False 会返回一个新的数据集


print('----------------------------------------修改---------------------------------')
df9 = df3.copy(deep=True)
print(df9)

# 4.1.1  修改行索引值

df10 = df9.rename(index={0: 'one', 2: 'two'})
print(df9)# 这样是没有改变的,也就是原值没有发生变化
print(df10)

# 补充：修改新的索引
# set_index


# 4.1.2  修改列索引值
df11 = df9.rename(columns={"name":"姓名", "age":"年龄"})
print(df11)


# 4.1.3   同时修改行和列索引值
df12 = df9.rename(index={0: 'one', 2: 'two'}, columns={"name":"姓名", "age":"年龄"})
print(df12)


# 4.1.4  修改单个值
# loc[]	只能使用标签索引，不能使用整数索引，通过标签索引切边进行筛选时
# iloc[]	只能使用整数索引，不能使用标签索引，通过整数索引切边进行筛选时
# at[]	只能使用标签索引，使用时必须输入两个参数，即行索引和列索引
# iat[]	只能使用整数索引，使用时必须输入两个参数，即行索引和列索引
# 执行速度：iat [] > at [] > iloc [] > loc []

# 注意：如果修改的是副本的值的话，容易引起copywarnning

print(df1)
df1.loc[0]['bookname']='java'
print(df1)


# 4.1.5  批量修改某个值
new_data = df1.replace("java", "python")
print(new_data)


# 4.1.6  修改某个区域的值

df13 = pd.DataFrame([['11','12','13','14'],['51','54','67','90']], columns=['bookname','author','price','date'])
print(df13)

df1.iloc[[0, 1]] = df13
print(df1)
